D:\git\skunkworks\herald-for-cpp\herald\src\datatype\distribution.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | // Copyright 2021 Herald Project Contributors |
2 | | // SPDX-License-Identifier: Apache-2.0 |
3 | | // |
4 | | |
5 | | #include "herald/datatype/distribution.h" |
6 | | |
7 | | #include <limits> |
8 | | #include <cmath> |
9 | | |
10 | | namespace herald { |
11 | | namespace datatype { |
12 | | |
13 | | Distribution::Distribution() noexcept |
14 | | : n(0), |
15 | | m1(0.0), |
16 | | m2(0.0), |
17 | | minimum(std::numeric_limits<double>::max()), |
18 | | maximum(std::numeric_limits<double>::min()) |
19 | 9 | { |
20 | 9 | ; |
21 | 9 | } |
22 | | |
23 | | Distribution::Distribution(double x, std::size_t frequency) noexcept |
24 | | : n(frequency), |
25 | | m1(x), |
26 | | m2(0), |
27 | | minimum(x), |
28 | | maximum(x) |
29 | 1 | { |
30 | 1 | ; |
31 | 1 | } |
32 | | |
33 | | void |
34 | | Distribution::add(double x) noexcept |
35 | 23 | { |
36 | 23 | // Update count, mean, variance |
37 | 23 | std::size_t n1 = n; |
38 | 23 | ++n; |
39 | 23 | double delta = x - m1; |
40 | 23 | double delta_n = delta / n; |
41 | 23 | double term1 = delta * delta_n * n1; |
42 | 23 | m1 += delta_n; |
43 | 23 | m2 += term1; |
44 | 23 | // update min, max |
45 | 23 | if (x < minimum) { |
46 | 7 | minimum = x; |
47 | 7 | } |
48 | 23 | if (x > maximum) { |
49 | 22 | maximum = x; |
50 | 22 | } |
51 | 23 | } |
52 | | |
53 | | void |
54 | | Distribution::add(double x, std::size_t frequency) noexcept |
55 | 0 | { |
56 | 0 | for (std::size_t i = 0;i < frequency;++i) { |
57 | 0 | add(x); |
58 | 0 | } |
59 | 0 | } |
60 | | |
61 | | void |
62 | | Distribution::add(const Distribution& other) noexcept |
63 | 1 | { |
64 | 1 | if (0 == n) { |
65 | 0 | n = other.n; |
66 | 0 | m1 = other.m1; |
67 | 0 | m2 = other.m2; |
68 | 0 | minimum = other.minimum; |
69 | 0 | maximum = other.maximum; |
70 | 0 | return; |
71 | 0 | } |
72 | 1 | // Combine distribution if this distribution is not empty |
73 | 1 | std::size_t new_n = n + other.n; |
74 | 1 | |
75 | 1 | double delta = other.m1 - m1; |
76 | 1 | double delta2 = delta * delta; |
77 | 1 | |
78 | 1 | m1 = ((n * m1) + (other.n * other.m1)) / new_n; |
79 | 1 | m2 = m2 + other.m2 + ((delta2 * n * other.n) / new_n); |
80 | 1 | |
81 | 1 | // set values |
82 | 1 | n = new_n; |
83 | 1 | minimum = minimum < other.minimum ? minimum : other.minimum0 ; |
84 | 1 | maximum = maximum > other.maximum ? maximum0 : other.maximum; |
85 | 1 | } |
86 | | |
87 | | const std::size_t |
88 | | Distribution::count() const noexcept |
89 | 10 | { |
90 | 10 | return n; |
91 | 10 | } |
92 | | |
93 | | const double |
94 | | Distribution::mean() const noexcept |
95 | 20 | { |
96 | 20 | return m1; |
97 | 20 | } |
98 | | |
99 | | const double |
100 | | Distribution::variance() const noexcept |
101 | 14 | { |
102 | 14 | if (n < 2) { // guard |
103 | 3 | return 0; |
104 | 3 | } |
105 | 11 | return m2 / (n - 1); |
106 | 11 | } |
107 | | |
108 | | const double |
109 | | Distribution::standardDeviation() const noexcept |
110 | 9 | { |
111 | 9 | if (n < 2) { // guard |
112 | 3 | return 0; |
113 | 3 | } |
114 | 6 | return std::sqrt(variance()); |
115 | 6 | } |
116 | | |
117 | | const double |
118 | | Distribution::min() const noexcept |
119 | 10 | { |
120 | 10 | return minimum; |
121 | 10 | } |
122 | | |
123 | | const double |
124 | | Distribution::max() const noexcept |
125 | 10 | { |
126 | 10 | return maximum; |
127 | 10 | } |
128 | | |
129 | | Distribution::operator std::string() const noexcept |
130 | 1 | { |
131 | 1 | return "[count=" + std::to_string(count()) + ",mean=" + std::to_string(mean()) + |
132 | 1 | ",sd=" + std::to_string(standardDeviation()) + ",min=" + std::to_string(min()) + |
133 | 1 | ",max=" + std::to_string(max()) + "]"; |
134 | 1 | } |
135 | | |
136 | | void |
137 | | Distribution::reset() noexcept |
138 | 2 | { |
139 | 2 | n = 0; |
140 | 2 | m1 = 0.0; |
141 | 2 | m2 = 0.0; |
142 | 2 | minimum = std::numeric_limits<double>::max(); |
143 | 2 | maximum = std::numeric_limits<double>::min(); |
144 | 2 | } |
145 | | |
146 | | } |
147 | | } |